package org.qiyu.live.bank.provider.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import jakarta.annotation.Resource;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.rocketmq.client.producer.MQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.qiyu.live.bank.constants.PayOrderStatusEnum;
import org.qiyu.live.bank.dto.PayOrderDTO;
import org.qiyu.live.bank.dto.PayProductDTO;
import org.qiyu.live.bank.interfaces.IPayProductRpc;
import org.qiyu.live.bank.interfaces.IQiyuCurrencyAccountRpc;
import org.qiyu.live.bank.provider.dao.mapper.IPayOrderMapper;
import org.qiyu.live.bank.provider.dao.po.PayOrderPO;
import org.qiyu.live.bank.provider.service.IPayOrderService;
import org.qiyu.live.bank.provider.service.IPayTopicService;
import org.qiyu.live.common.interfaces.utils.ConvertBeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.UUID;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: sfx
 * Date: 2023-11-06
 * Time: 21:37
 */
@Service
public class PayOrderServiceImpl implements IPayOrderService {

    private Logger LOGGER = LoggerFactory.getLogger(PayOrderServiceImpl.class);

    @Resource
    private IPayOrderMapper payOrderMapper;
    @Resource
    private MQProducer mqProducer;
    @Resource
    private IPayTopicService payTopicService;
    @DubboReference
    private IPayProductRpc payProductRpc;
    @DubboReference
    private IQiyuCurrencyAccountRpc currencyAccountRpc;

    @Override
    public String insertOne(PayOrderDTO payOrderDTO) {
        String orderId = UUID.randomUUID().toString();
        PayOrderPO payOrderPO = ConvertBeanUtils.convert(payOrderDTO, PayOrderPO.class);
        payOrderPO.setOrderId(orderId);
        payOrderMapper.insert(payOrderPO);
        return orderId;
    }

    @Override
    public boolean updateOrderStatus(Integer id, Integer status) {
        LambdaUpdateWrapper<PayOrderPO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(PayOrderPO::getId, id);
        updateWrapper.set(PayOrderPO::getStatus, status);
        int update = payOrderMapper.update(new PayOrderPO(), updateWrapper);
        return update >= 1;
    }

    @Override
    public boolean updateOrderStatus(String orderId, Integer status) {
        LambdaUpdateWrapper<PayOrderPO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(PayOrderPO::getOrderId, orderId);
        updateWrapper.set(PayOrderPO::getStatus, status);
        int update = payOrderMapper.update(new PayOrderPO(), updateWrapper);
        return update >= 1;
    }

    @Override
    public boolean payNotify(PayOrderDTO payOrderDTO) {
        // 1. 查询订单对象
        PayOrderPO payOrderPO = this.getPayOrderByOrderId(payOrderDTO.getOrderId());
        if (payOrderPO == null) {
            LOGGER.info("[payNotify] payOrderPo is null");
            return false;
        }
        // 我们支付成功之后要通知用户已经支付成功
        // 2. 我们要根据业务code,查询对应的topic,发送MQ消息
        String bizCode = payTopicService.getTopicByBizCode(payOrderDTO.getBizCode());
        if (bizCode == null || StringUtils.isEmpty(bizCode)) {
            LOGGER.info("[payNotify] bizCode is null");
            return false;
        }
        // 3. 修改订单状态 && 增加用户余额虚拟币
        payNotifyHandler(payOrderDTO);
        // 4. MQ的发送
        Message message = new Message();
        message.setBody(JSON.toJSONBytes(payOrderPO));
        message.setTopic(bizCode);
        try {
            SendResult sendResult = mqProducer.send(message);
            LOGGER.info("[PayOrderServiceImpl] message is {}", sendResult);
        } catch (Exception e) {
            LOGGER.error("[PayOrderServiceImpl] send message error", e);
        }
        return true;
    }

    private void payNotifyHandler(PayOrderDTO payOrderDTO) {
        // 1. 更新订单状态为已支付
        this.updateOrderStatus(payOrderDTO.getOrderId(), PayOrderStatusEnum.HAVE_PAID.getCode());
        // 2. 增加用户余额虚拟币
        // 2.1 查询用户购买的产品
        Integer productId = payOrderDTO.getProductId();
        PayProductDTO payProductDTO = payProductRpc.getPayProductById(productId);
        JSONObject jsonObject = JSON.parseObject(payProductDTO.getExtra());
        // 2.2 得到产品对应的虚拟币值
        int num = jsonObject.getInteger("coin");
        // 2.3 增加用户的虚拟币值,并且记录相应的流水记录
        currencyAccountRpc.incr(payOrderDTO.getUserId(), num);
    }

    @Override
    public PayOrderPO getPayOrderByOrderId(String orderId) {
        LambdaQueryWrapper<PayOrderPO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PayOrderPO::getOrderId, orderId);
        queryWrapper.last("limit 1");
        return payOrderMapper.selectOne(queryWrapper);
    }
}